const jwt = require("jsonwebtoken");
const { setAccessToken, setRefreshToken } = require("../utils/token");
const {
  refreshToken_IS_REQUIRED,
  accessToken_IS_INVALID,
  accessToken_IS_REQUIRED,
  refreshToken_IS_INVALID,
} = require("../config/error-constants");
const { PUBLIC_KEY } = require("../config/secret");
const {
  AccessTokenInvalid,
  AccessToken,
  RefreshToken,
  RefreshTokenInvalid,
} = require("../config/tokenHeader-constants");

/*
  验证长token是否有效，刷新短token
  这里要注意，在刷新短token的时候回也返回新的长token，延续长token，
  这样活跃用户在持续操作过程中不会被迫退出登录。长时间无操作的非活
  跃用户长token过期重新登录
*/
const refresh = async (ctx, next) => {
  const { id, account } = ctx.query;

  // 1.获取请求头中携带的长token
  const refreshToken = ctx.headers[RefreshToken];
  console.log(refreshToken);
  if (!refreshToken) {
    return ctx.app.emit("error", refreshToken_IS_REQUIRED, ctx);
  }
  const token = refreshToken.replace("Bearer ", "");

  //解析token 参数 token 密钥 回调函数返回信息
  try {
    const result = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ["RS256"],
    });

    // 设置Access-Token和Refresh-Token响应头
    ctx.set(AccessToken, setAccessToken({ id, account }));
    ctx.set(RefreshToken, setRefreshToken({ id, account }));

    // 验证通过的逻辑
    ctx.body = {
      code: 200,
      msg: "长token有效，返回新的token",
      data: null,
    };
  } catch (error) {
    console.log(error);
    // 设置refresh-token失效的响应头
    ctx.set(RefreshTokenInvalid, "Refresh Token is invalid");
    // 错误处理逻辑
    ctx.app.emit("error", refreshToken_IS_INVALID, ctx);
  }
};

/* 
 验证短token是否有效 
 验证用户是否授权
 */
const verifyAuth = async (ctx, next) => {
  // 1.获取请求头中携带的短token
  const accessToken = ctx.headers[AccessToken];
  console.log(accessToken);

  if (!accessToken) {
    return ctx.app.emit("error", accessToken_IS_REQUIRED, ctx);
  }
  const token = accessToken.replace("Bearer ", "");

  // 2.验证token是否有效
  try {
    // 2.1获取token中的信息
    const result = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ["RS256"],
    });

    // 2.2将token的信息保留下来
    ctx.userInfo = result;

    // 2.3验证成功执行下一个中间件

    await next();
  } catch (error) {
    // 设置access-token失效的响应头
    ctx.set(AccessTokenInvalid, "Access Token is invalid"); // 设置响应头信息
    ctx.app.emit("error", accessToken_IS_INVALID, ctx);
    // console.log("====", error.name);
    // if (error.name === "JsonWebTokenError") {
    //   ctx.app.emit("error", UNAUTHORIZATION, ctx);
    // } else {
    //   console.log("====", error);
    // }
  }
};

module.exports = {
  refresh,
  verifyAuth,
};
